import { Injectable, Logger } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository, LessThan, MoreThan } from "typeorm";
import { PrivateMessageEntity } from "../entities/private-message.entity";
import { CharacterService } from "./character.service";

@Injectable()
export class PrivateMessageService {
  private readonly logger = new Logger(PrivateMessageService.name);

  constructor(
    @InjectRepository(PrivateMessageEntity)
    private privateMessageRepository: Repository<PrivateMessageEntity>,
    private characterService: CharacterService
  ) { }

  /**
   * 发送私信消息
   * @param messageData 私信消息数据
   * @param pushNotificationCallback 推送通知回调函数
   * @returns 发送成功的消息
   */
  async sendPrivateMessage(
    messageData: {
      content: string;
      senderCharacterId: number;
      receiverCharacterId: number;
      messageType?: number; // 消息类型：1-玩家消息，2-系统消息
    },
    pushNotificationCallback?: (
      receiverCharacterId: number,
      senderCharacterId: number
    ) => void
  ) {
    try {
      // 验证消息内容
      if (!messageData.content || messageData.content.trim().length === 0) {
        throw new Error("消息内容不能为空");
      }

      if (messageData.content.length > 500) {
        throw new Error("消息内容过长，不能超过500个字符");
      }

      // 验证接收者角色是否存在
      const receiverCharacter = await this.characterService.getCharacterById(
        messageData.receiverCharacterId
      );

      if (!receiverCharacter) {
        throw new Error("接收者角色不存在");
      }

      // 如果是玩家消息，需要验证发送者角色
      let senderCharacter = null;
      if (messageData.messageType !== 2) {
        senderCharacter = await this.characterService.getCharacterById(
          messageData.senderCharacterId
        );

        if (!senderCharacter) {
          throw new Error("发送者角色不存在");
        }

        // 不能给自己发私信
        if (messageData.senderCharacterId === messageData.receiverCharacterId) {
          throw new Error("不能给自己发送私信");
        }
      }

      // 生成消息时间显示格式
      const now = new Date();
      const messageTime = `${now.getFullYear()}-${(now.getMonth() + 1)
        .toString()
        .padStart(2, "0")}-${now.getDate().toString().padStart(2, "0")} ${now
          .getHours()
          .toString()
          .padStart(2, "0")}:${now.getMinutes().toString().padStart(2, "0")}:${now
            .getSeconds()
            .toString()
            .padStart(2, "0")}`;

      // 创建私信消息
      const privateMessage = this.privateMessageRepository.create({
        content: messageData.content.trim(),
        senderName: senderCharacter?.name || '系统', // 系统消息时使用默认名称
        senderCharacterId: messageData.senderCharacterId,
        receiverName: receiverCharacter.name,
        receiverCharacterId: messageData.receiverCharacterId,
        messageTime: messageTime,
        isActive: 1,
        isRead: 0,
        status: 0,
        messageType: messageData.messageType || 1, // 默认为玩家消息
      });

      const savedMessage = await this.privateMessageRepository.save(
        privateMessage
      );

      // 记录发送成功的消息
      const senderName = senderCharacter?.name || '系统';
      this.logger.log(
        `✅ 私信发送成功: ${senderName} -> ${receiverCharacter.name}: ${messageData.content}`
      );

      // 如果提供了推送通知回调，则调用它
      if (pushNotificationCallback) {
        try {
          pushNotificationCallback(
            messageData.receiverCharacterId,
            messageData.senderCharacterId
          );
        } catch (error) {
          this.logger.error("推送私信通知失败:", error);
        }
      }

      return savedMessage;
    } catch (error) {
      this.logger.error("发送私信失败:", error);
      throw error;
    }
  }

  /**
   * 获取与指定角色的私信记录列表
   * @param characterId 当前角色ID
   * @param targetCharacterId 目标角色ID
   * @param limit 限制数量
   * @returns 私信记录列表
   */
  async getPrivateMessageList(
    characterId: number,
    targetCharacterId: number,
    limit: number = 50
  ) {
    try {
      // 查询两个角色之间的所有私信记录
      const messages = await this.privateMessageRepository
        .createQueryBuilder("message")
        .where(
          "((message.senderCharacterId = :characterId AND message.receiverCharacterId = :targetCharacterId) OR (message.senderCharacterId = :targetCharacterId AND message.receiverCharacterId = :characterId))",
          { characterId, targetCharacterId }
        )
        .andWhere("message.isActive = :isActive", { isActive: 1 })
        .andWhere("message.status = :status", { status: 0 })
        .orderBy("message.created_at", "DESC")
        .limit(limit)
        .getMany();

      // 转换为客户端期望的格式
      return messages.map((msg) => ({
        content: msg.content,
        date: msg.messageTime,
        fname: msg.senderCharacterId === characterId ? "我" : msg.senderName,
      }));
    } catch (error) {
      this.logger.error("获取私信记录失败:", error);
      throw error;
    }
  }

  /**
   * 获取角色的私信列表（按联系人分组）
   * @param characterId 角色ID
   * @returns 私信联系人列表
   */
  async getPrivateMessageContacts(characterId: number) {
    try {
      // 查询该角色作为发送者或接收者的所有私信联系人
      const contacts = await this.privateMessageRepository
        .createQueryBuilder("message")
        .select([
          "CASE WHEN message.senderCharacterId = :characterId THEN message.receiverCharacterId ELSE message.senderCharacterId END as contactId",
          "CASE WHEN message.senderCharacterId = :characterId THEN message.receiverName ELSE message.senderName END as contactName",
          "MAX(message.created_at) as lastMessageTime",
          "MAX(CASE WHEN message.receiverCharacterId = :characterId AND message.isRead = 0 THEN 1 ELSE 0 END) as hasUnread",
        ])
        .where(
          "(message.senderCharacterId = :characterId OR message.receiverCharacterId = :characterId)"
        )
        .andWhere("message.isActive = :isActive", { isActive: 1 })
        .andWhere("message.status = :status", { status: 0 })
        .setParameter("characterId", characterId)
        .groupBy("contactId, contactName")
        .orderBy("lastMessageTime", "DESC")
        .getRawMany();

      return contacts;
    } catch (error) {
      this.logger.error("获取私信联系人失败:", error);
      throw error;
    }
  }

  /**
   * 标记私信为已读
   * @param characterId 角色ID
   * @param senderCharacterId 发送者角色ID
   */
  async markAsRead(characterId: number, senderCharacterId: number) {
    try {
      await this.privateMessageRepository
        .createQueryBuilder()
        .update(PrivateMessageEntity)
        .set({ isRead: 1 })
        .where("receiverCharacterId = :characterId", { characterId })
        .andWhere("senderCharacterId = :senderCharacterId", {
          senderCharacterId,
        })
        .andWhere("isRead = :isRead", { isRead: 0 })
        .execute();

      this.logger.log(
        `✅ 私信已标记为已读: ${senderCharacterId} -> ${characterId}`
      );
    } catch (error) {
      this.logger.error("标记私信已读失败:", error);
      throw error;
    }
  }

  /**
   * 批量标记与某人的所有私信为已读
   */
  async markAllAsRead(characterId: number, otherId: number) {
    try {
      await this.privateMessageRepository
        .createQueryBuilder()
        .update(PrivateMessageEntity)
        .set({ isRead: 1 })
        .where(
          "(receiverCharacterId = :characterId AND senderCharacterId = :otherId) OR (receiverCharacterId = :otherId AND senderCharacterId = :characterId)",
          { characterId, otherId }
        )
        .andWhere("isRead = :isRead", { isRead: 0 })
        .andWhere("isActive = :isActive", { isActive: 1 })
        .execute();
      this.logger.log(
        `✅ 私信批量已读: ${otherId} <-> ${characterId}`
      );
    } catch (error) {
      this.logger.error("批量标记私信已读失败:", error);
      throw error;
    }
  }

  /**
   * 获取未读私信数量
   * @param characterId 角色ID
   * @returns 未读私信数量
   */
  async getUnreadCount(characterId: number) {
    try {
      const count = await this.privateMessageRepository.count({
        where: {
          receiverCharacterId: characterId,
          isRead: 0,
          isActive: 1,
          status: 0,
        },
      });

      return count;
    } catch (error) {
      this.logger.error("获取未读私信数量失败:", error);
      return 0;
    }
  }

  /**
   * 获取最新的未读私信
   * @param characterId 角色ID
   * @returns 最新的未读私信
   */
  async getLatestUnreadMessage(characterId: number) {
    try {
      const message = await this.privateMessageRepository.findOne({
        where: {
          receiverCharacterId: characterId,
          isRead: 0,
          isActive: 1,
        },
        order: {
          created_at: "DESC",
        },
      });

      return message;
    } catch (error) {
      this.logger.error("获取最新未读私信失败:", error);
      return null;
    }
  }

  /**
   * 获取最近的未读私信列表
   * @param characterId 角色ID
   * @param limit 限制数量，默认5条
   * @returns 最近的未读私信列表
   */
  async getRecentUnreadMessages(characterId: number, limit: number = 5) {
    try {
      const messages = await this.privateMessageRepository.find({
        where: {
          receiverCharacterId: characterId,
          isRead: 0,
          isActive: 1,
          status: 0,
        },
        order: {
          created_at: "DESC",
        },
        take: limit,
      });

      return messages;
    } catch (error) {
      this.logger.error("获取最近未读私信列表失败:", error);
      return [];
    }
  }

  /**
   * 删除私信消息
   * @param messageId 消息ID
   * @param characterId 角色ID（只能删除自己发送或接收的消息）
   */
  async deleteMessage(messageId: number, characterId: number) {
    try {
      const message = await this.privateMessageRepository.findOne({
        where: { id: messageId },
      });

      if (!message) {
        throw new Error("消息不存在");
      }

      if (
        message.senderCharacterId !== characterId &&
        message.receiverCharacterId !== characterId
      ) {
        throw new Error("无权删除此消息");
      }

      // 软删除：标记为已删除
      await this.privateMessageRepository.update(messageId, {
        isActive: 0,
        status: 2,
      });

      this.logger.log(`✅ 私信已删除: ${messageId}`);
      return true;
    } catch (error) {
      this.logger.error("删除私信失败:", error);
      throw error;
    }
  }
}
